#ifndef _H_SHAPE_SPHERE
#define _H_SHAPE_SPHERE
#include "../core/heads.hpp"
#include "../core/geometry.hpp"
#include "../core/interaction.hpp"
#include "../core/shape.hpp"
namespace chen {
class Sphere : public Shape {
public:
    Float r, _area;
    inline Sphere (
        const Transform * w2o, const Material * mat, const Float & rr):
        Shape(w2o, mat), r(rr) {
        Shape::wbnd = this->w2o->reversed(Bound3(
            Point3(-r, -r, -r),
            Point3(r, r, r)
        ));
        flags = FSHAPE_SUPUSP|FSHAPE_SUPUSPFR;
        // Note that the area is a constant despite scaling trasforms
        _area = (Float)(4*M_PI)*r*r;//*product<3>(w2o->scales());
    }
    bool interact (const Ray & r, SurfInteract * si) const;
    bool mask (const Ray & r) const;
    const Bound3 & worldBound () const ;
    inline Float area () const {
        return _area;
    }
    void uniformSample (const Point2 & u, Interact * in, Point2 * uv, Float * pdf) const ;

    // Sample a point possibly visible to a surface interaction
    // Note that the PDF here is defined that integral over (one sided)
    // surface area equals to 1.
    void uniformSampleFrom (const Point2 & u, const Interact & from, Interact * in, Point2 * uv, Float * pdf) const ;
};
}
#endif